Crate crrl

source ·
Expand description

Crrl is a Rust library for cryptographic research.

This library implements computations in some finite fields and elliptic curves. It aims at providing efficient and secure (constant-time) implementations, but with portable code, and with a convenient API so that scalars, curve points, and other field elements may be used in straightforward expressions with normal arihtmetic operators.

Finite fields are implemented through some customizable types defined in backend (a 32-bit and a 64-bit backends are provided, the “right one” is automatically selected, unless overridden by a compile-time feature). The types may support several distinct moduli, chosen through compile-time type parameter.

Curve edwards25519 is implemented in the ed25519 module. The specialized X25519 function is in x25519. The prime-order group ristretto255 (internally based on edwards25519) is defined in the ristretto255 module. NIST curve P-256 (aka “secp256r1” and “prime256v1”) is implemented in the p256 module (with the ECDSA signature algorithm). Double-odd curves jq255e and jq255s are implemented by jq255e and jq255s, respectively (including signature and key exchange schemes). Secp256k1 is implemented in secp256k1. Edwards448 is in ed448, while the specialized X448 function is in x448. The prime-order decaf448 group is implemented in decaf448.

Usage

The library is “mostly no_std”. By default, it compiles against the standard library. It can be compiled in no_std mode, in which case all functionality is still available, except verification of truncated ECDSA signatures with curve P-256.

Conventions

All implemented functions should be strictly constant-time, unless explicitly documented otherwise (non-constant-time functions normally have “vartime” in their name). In order to avoid unwanted side-channel leaks, Booleans are avoided (compilers tend to “optimize” things a bit too eagerly when handling bool values). All functions that return or use a potentially secret Boolean value use the u32 type; the convention is that 0xFFFFFFFF means “true”, and 0x00000000 means “false”. No other value shall be used, for they would lead to unpredictable results. Similarly, the Eq or PartialEq traits are not implemented.

Algebraic operations on field elements and curve points are performed with the usual operators (e.g. +); appropriate traits are defined so that structure types and pointers to structure types can be used more or less interchangeably. Throughout the code, functions that modify the object on which they are called tend to have a name in set_*() (e.g. for a curve point P, if we want to compute the double of that point, then P.set_double() modifies the point structure in place, while P.double() leaves P unmodified and returns the double as a new structure instance).

Truncated Signatures

Apart from standard support for curve operations and signature algorithms, truncated signatures are implemented for both Ed25519 (Schnorr signatures over edwards25519) and ECDSA (over P-256). A truncated signature is a shrunk version, by up to 32 bits, of a normal signature; the verification process is then more expensive, though not necessarily intolerably expensive, depending on usage context (the most expensive verification function is for ECDSA on P-256, with maximal 32-bit truncation; in that case, verification cost can be up to about 0.65 seconds on a 500 MHz ARM Cortex A53; but Ed25519 signatures with 32-bit truncation can be verified in less than 0.05 seconds on the same hardware). Signature truncation can be useful in situations with strong I/O constraints, where every data bit counts, but where use of fully standard Ed25519 or ECDSA signature generators is made mandatory because of some regulatory or physical constraints of the signing hardware.

Performance

On an Intel i5-8259U CPU (Coffee Lake core), Ed25519 signatures have been benchmarked at about 51600 cycles for signing, 111000 cycles for verification; these are not bad values, and are competitive or at least within 30% of performance obtained from assembly-optimized implementations on the same hardware. For P-256, signing time is about 125000 cycles, verification is 256000 cycles. For the jq255e curve, signatures are generated in about 54700 cycles, and verified in only 82800 cycles (56200 and 86800, respectively, for jq255s). These figures have been obtained by compiling with Rust 1.59 in release mode, with the flags -C target-cpu=native.

On an ARM Cortex A53 (RaspberryPi Model 3B), Ed25519 signing was measured at 213000 cycles, verification at 479000 cycles; for P-256, the figures were 389000 and 991000, respectively. With jq255e, signature generation and verification use 241000 and 358000 cycles, respectively (248000 and 369000 for jq255s).

No inline assembly is used. On x86-64 architectures, the _addcarry_u64() and _subborrow_u64() intrinsics are used (from core::arch::x86_64); however, plain implementations with no intrinsics are available (and used on, for instance, aarch64).

Modules

  • Architecture-specific implementations of finite fields.
  • Decaf448 implementation.
  • Edwards448 curve implementation.
  • Edwards25519 curve implementation.
  • Finite fields.
  • FROST implementation.
  • Jq255e implementation.
  • Jq255s implementation.
  • LMS implementation.
  • NIST P-256 curve implementation.
  • Ristreto255 implementation.
  • secp256k1 curve implementation.
  • X448 key-exchange algorithm.
  • X25519 key-exchange algorithm.

Macros

Structs

  • The rand_core types are re-exported so that users of crrl do not have to worry about using the exact correct version of rand_core. Error type of random number generators

Traits

  • The rand_core types are re-exported so that users of crrl do not have to worry about using the exact correct version of rand_core. A marker trait used to indicate that an RngCore or BlockRngCore implementation is supposed to be cryptographically secure.
  • The rand_core types are re-exported so that users of crrl do not have to worry about using the exact correct version of rand_core. The core of a random number generator.